#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

#define LEFT "["
#define RIGHT "]"
#define LABLE "#"
#define DELIM " \t"
#define LINE_SIZE 1024
#define ARGC_SIZE 32
#define EXIT_CODE 44

int lastcode = 0;
int quit = 0;
extern char **environ;
char commandline[LINE_SIZE];
char *argv[ARGC_SIZE];
char pwd[LINE_SIZE];
char myenv[LINE_SIZE];


const char *mygetusername()
{
    return getenv("USER");
}

const char *mygethostname()
{
    return getenv("HOSTNAME");
}

void getpwd()
{
    getcwd(pwd,sizeof(pwd));//把当前路径存到缓冲区里，这里也就是pwd
}

void interact(char *cline,int size)
{
    getpwd();
    printf(LEFT"%s@%s %s"RIGHT""LABLE" ", mygetusername(), mygethostname(), pwd);
    char *s = fgets(cline,size,stdin);
    assert(s);
    (void)s;
    cline[strlen(cline)-1]='\0';
}

int splitstring(char *cline, char *_argv[])
{
    int i = 0;
    _argv[i++]=strtok(cline,DELIM);
    while(_argv[i++]=strtok(NULL,DELIM));
    return i-1;
}

void NormalExcute(char *_argv[])
{
    pid_t id = fork();
    if(id<0)
    {
        perror("fork");
        return;
    }
    else if(id == 0)
    {
        execvp(_argv[0],_argv);
        exit(EXIT_CODE);
    }
    else
    {
        int status = 0;
        pid_t rid = waitpid(id,&status,0);
        if(rid==id)
        {
            lastcode = WEXITSTATUS(status);
        }
    }
}

int buildCommand(char *_argv[],size_t _argc)
{
    if (_argc == 2 && strcmp(_argv[0], "cd") == 0) 
    {
        if (chdir(_argv[1]) != 0) 
        {
            perror("cd failed");
        } 
        else
        {
            getpwd();  // 更新当前路径
            setenv("PWD", pwd, 1);  // ✅ 安全设置环境变量
        }
        return 1;
    }

    else if(_argc == 2 && strcmp(_argv[0], "export") == 0)
    {
        strcpy(myenv,_argv[1]);
        putenv(myenv);
        return 1;
    }
    //echo 123、 echo $变量名、 echo $?
    else if(_argc == 2 && strcmp(_argv[0], "echo") == 0)
    {
        //echo $?  返回上一个指令的退出码
        if(strcmp(_argv[1],"$?")==0)
        {
            printf("%d\n",lastcode);
            lastcode=0;
        }
        //echo $环境变量
        else if(*_argv[1]="$")
        {
            char *val = getenv(_argv[1]+1);
            if(val)
                printf("%s\n",val);
        }
        //echo ***
        else
        {
            printf("%s\n",_argv[1]);
        }
        return 1;
    }

    
    if(strcmp(_argv[0], "ls") == 0)
    {
        _argv[_argc++] = "--color";
        _argv[_argc] = NULL;
    }


    return 0;
}



int main()
{
    while(!quit)
    {
        // 交互，获取命令行
        interact(commandline,sizeof(commandline));
        
        // 分割命令行字符
        int argc = splitstring(commandline,argv);
        if(argc == 0)
        {
            continue;
        }
        
        //指令判断
        //内键指令
        int n = buildCommand(argv,argc);

        //普通指令
        if(!n)
            NormalExcute(argv);
        
        

    }

    return 0;
}
